﻿#ifndef DATETIMETIMER_H
#define DATETIMETIMER_H

#include <QObject>
#include <QTimer>
#include <QDateTime>

/**
 * @brief The DateTimeTimer class 以具体的日期时间为依据的定时器。
 * 可以设定每天某个特定时刻发出 timeout 信号。
 * 也可以以半天为间隔。
 * 也可以是每个小时的特定分钟发出 timeout 信号。
 */
class DateTimeTimer : public QObject
{
    Q_OBJECT
public:
    enum INTERVAL{E_DAY, E_HALFDAY, E_HOUR, E_MINUTE};
    explicit DateTimeTimer(QObject *parent = nullptr);
    bool isSingleShot() const {return m_timer.isSingleShot();}
    void setSingleShot(bool s) {m_timer.setSingleShot(s);}
    void setInterval(INTERVAL v) {m_interval = v;}
    INTERVAL interval() {return m_interval;}
    /**
     * @brief singleShot
     * @param dt 受限于 QTimer 的实现，在 Win 平台上 只能设置 576 小时之内的日期。大约 24 天。
     * @param receiver
     * @param member
     */
    static bool singleShot(const QDateTime &dt, const QObject *receiver, const char *member);
    static bool singleShot(const QDateTime &dt, Qt::TimerType timerType, const QObject *receiver, const char *member);
    static bool singleShot(const QTime &t, const QObject *receiver, const char *member);
    static bool singleShot(const QTime &t, Qt::TimerType timerType, const QObject *receiver, const char *member);

signals:
    void timeout();

public slots:
    bool start(const QTime &t);
    bool start(const QDateTime &dt);
    void stop() {m_timer.stop();}

private slots:
    void onTimeout();

private:
    static int msecsTo(const QTime &t);
    static qint64 msecsTo(const QDateTime &dt);
    QTimer m_timer;
    QTime m_time;
    INTERVAL m_interval;
};

#endif // DATETIMETIMER_H
